#include <stddef.h>
#include <stdlib.h>
#include "mem.h"
#include <stdio.h>
#define HEAP_SIZE  (32 * 1024)  
static uint8_t g_heap[HEAP_SIZE] __attribute__((aligned(8)));
typedef struct {
    uint32_t size : 31;  
    uint32_t used : 1;   
} block_header_t;

void heap_init()
{
    block_header_t* header = (block_header_t*)g_heap;
    header->size = HEAP_SIZE - sizeof(block_header_t);
    header->used = 0;
}

void* __wrap_malloc(size_t size) 
{
    size = (size + 7) & ~7;

    block_header_t* header = (block_header_t*)g_heap;
    while ((uint8_t*)header < g_heap + HEAP_SIZE) {
        if (!header->used && header->size >= size) {
            if (header->size > size + sizeof(block_header_t)) {
                block_header_t* new_block = (block_header_t*)((uint8_t*)header + sizeof(block_header_t) + size);
                new_block->size = header->size - size - sizeof(block_header_t);
                new_block->used = 0;
                header->size = size;
            }
            header->used = 1;
            return (uint8_t*)header + sizeof(block_header_t);
        }
        header = (block_header_t*)((uint8_t*)header + sizeof(block_header_t) + header->size);
    }
    return NULL;  
}

void __wrap_free(void* ptr) 
{
    if (!ptr) return;
    
    block_header_t* header = (block_header_t*)((uint8_t*)ptr - sizeof(block_header_t));
    header->used = 0;

    block_header_t* next = (block_header_t*)((uint8_t*)header + sizeof(block_header_t) + header->size);
    if ((uint8_t*)next < g_heap + HEAP_SIZE && !next->used) {
        header->size += sizeof(block_header_t) + next->size;
    }
}





